package com.focusai.efairy.network;

import com.focusai.efairy.utils.log.Log;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.net.ssl.SSLException;

import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;

/**
 * Created by heqingbao on 2016/7/23.
 */
public class RetryInterceptor implements Interceptor {
    private static final String TAG = RetryInterceptor.class.getSimpleName();

    private static Map<Request, Integer> retryMapper = new HashMap<>();
    private static final int MAX_RETRY_COUNT = 2;

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();

        Response response;
        try {
            response = chain.proceed(request);
        } catch (Exception e) {
            Log.E(TAG,"请求失败:" + request.url(), e);
            if (isRetryableException(e)) {
                response = retryRequest(chain, request);
            } else {
                throw e;
            }
        }

        synchronized (retryMapper) {
            retryMapper.remove(request);
        }

        return response;
    }

    private Response retryRequest(Chain chain, Request request) throws IOException {
        Response response = null;
        try {
            Log.I(TAG,"重试请求" + request.url());
            response = chain.proceed(request);
        } catch (Exception e) {
            if (isRetryableException(e)) {
                synchronized (retryMapper) {
                    Integer resumeCount = retryMapper.get(request);
                    if (resumeCount == null) {
                        resumeCount = 1;
                        retryMapper.put(request, resumeCount);
                    }

                    if (resumeCount > MAX_RETRY_COUNT) {
                        return response;
                    }

                    retryMapper.put(request, resumeCount + 1);
                }

                response = retryRequest(chain, request);
            }
        }
        return response;
    }

    private boolean isRetryableException(Exception e) {
        // javax.net.ssl.SSLException: Read error: ssl=0xb7bed:I/O error during system call, Connection reset by peer
        return e instanceof SSLException && e.getMessage() != null && e.getMessage().contains("Connection reset by peer");
    }

    @Override
    public String toString() {
        // 防止混淆后不方便查看Log
        return "RetryInterceptor@" + Integer.toHexString(hashCode());
    }
}
